import { Engine } from "../../Engine";
import { guid } from "../../core/utils";
class Pass {
    static _instance = null;
    constructor() {
        this._swap = 0;
        this.swapAttach = [
        ];
        this._depthAttach = undefined;
        // this._positionAttach = undefined;
        this._pickAttach=undefined;
    }
    reset() {
        this._swap = 0;
    }
    swap() {//交换附件，read变为write
        this._swap = this._swap ^ 1;
    }
    static instance() {
        if (!Pass._instance) {
            Pass._instance = new Pass();
        }
        return Pass._instance;
    }
    get readAttach(){
        const swap=this._swap;
        let attach = this.swapAttach[swap];
        if (!attach) {
            attach = Engine.instance.device.createTexture({
                label:"swap",
                size: Engine.instance.size,
                format: Engine.instance.format,
                mipLevelCount: 1,
                sampleCount: 1,
                usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC,
            });
            attach.view = attach.createView({ label:"read"});
            attach.id=guid();
            this.swapAttach[swap] = attach;
        } else if (attach.width !== Engine.instance.size[0] || attach.height !== Engine.instance.size[1]) {
            attach.destroy();
            attach = Engine.instance.device.createTexture({
                label:"swap",
                size: Engine.instance.size,
                format: Engine.instance.format,
                sampleCount: 1,
                usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC,
            });
            attach.id=guid();
            attach.view = attach.createView();
            this.swapAttach[swap] = attach;
        }
        return attach;
    }
    get writeAttach(){
        const swap=this._swap ^ 1;
        let attach = this.swapAttach[swap];
        if (!attach) {
            attach = Engine.instance.device.createTexture({
                label:"swap",
                size: Engine.instance.size,
                format: Engine.instance.format,
                mipLevelCount: 1,
                sampleCount: 1,
                usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC,
            });
            attach.view = attach.createView({ label:"write"});
            attach.id=guid();
            this.swapAttach[swap] = attach;
        } else if (attach.width !== Engine.instance.size[0] || attach.height !== Engine.instance.size[1]) {
            attach.destroy();
            attach = Engine.instance.device.createTexture({
                label:"swap",
                size: Engine.instance.size,
                format: Engine.instance.format,
                sampleCount: 1,
                usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC,
            });
            attach.view = attach.createView();
            attach.id=guid();
            this.swapAttach[swap] = attach;
        }
        return attach;
    }
    get depthAttach(){
        if(!this._depthAttach){
            this._depthAttach =Engine.instance.device.createTexture({
                label:"depth",
                size: Engine.instance.size,
                format: 'depth24plus',
                sampleCount: 1,
                usage: GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING| GPUTextureUsage.COPY_SRC,
            });
            this._depthAttach.view=this._depthAttach.createView();
        }else if(this._depthAttach.width !== Engine.instance.size[0] || this._depthAttach.height !== Engine.instance.size[1]) {
            this._depthAttach.destroy();
            this._depthAttach =Engine.instance.device.createTexture({
                label:"depth",
                size: Engine.instance.size,
                format: 'depth24plus',
                sampleCount: 1,
                usage: GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING| GPUTextureUsage.COPY_SRC,
            });
            this._depthAttach.view=this._depthAttach.createView();
        }
        return this._depthAttach;
    }
    get postionTexture(){
        if(!this._postionTexture){
            this._postionTexture =Engine.instance.device.createTexture({
                label:"position",
                size: Engine.instance.size,
                format: "rgba32float",
                mipLevelCount: 1,
                sampleCount: 1,
                usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC,
            });
            this._postionTexture.view=this._postionTexture.createView();
        }else if(this._postionTexture.width !== Engine.instance.size[0] || this._postionTexture.height !== Engine.instance.size[1]) {
            this._postionTexture.destroy();
            this._postionTexture =Engine.instance.device.createTexture({
                label:"position",
                size: Engine.instance.size,
                format:"rgba32float",
                mipLevelCount: 1,
                sampleCount: 1,
                usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC,
            });
            this._postionTexture.view=this._postionTexture.createView();
        }
        return this._postionTexture;
    }
    get normalTexture(){
        if(!this._normalTexture){
            this._normalTexture =Engine.instance.device.createTexture({
                label:"normal",
                size: Engine.instance.size,
                format: "rgba16float",
                mipLevelCount: 1,
                sampleCount: 1,
                usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC,
            });
            this._normalTexture.view=this._normalTexture.createView();
        }else if(this._normalTexture.width !== Engine.instance.size[0] || this._normalTexture.height !== Engine.instance.size[1]) {
            this._normalTexture.destroy();
            this._normalTexture =Engine.instance.device.createTexture({
                label:"normal",
                size: Engine.instance.size,
                format:"rgba16float",
                mipLevelCount: 1,
                sampleCount: 1,
                usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC,
            });
            this._normalTexture.view=this._normalTexture.createView();
        }
        return this._normalTexture;
    }
    get pickAttach(){
        if(!this._pickAttach){
            this._pickAttach =Engine.instance.device.createTexture({
                label:"pick",
                size: Engine.instance.size,
                format: Engine.instance.format,
                mipLevelCount: 1,
                sampleCount: 1,
                usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC,
            });
            this._pickAttach.view=this._pickAttach.createView();
        }else if(this._pickAttach.width !== Engine.instance.size[0] || this._pickAttach.height !== Engine.instance.size[1]) {
            this._pickAttach.destroy();
            this._pickAttach =Engine.instance.device.createTexture({
                label:"pick",
                size: Engine.instance.size,
                format: Engine.instance.format,
                mipLevelCount: 1,
                sampleCount: 1,
                usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_SRC,
            });
            this._pickAttach.view=this._pickAttach.createView();
        }
        return this._pickAttach;
    }
    destroy(){
        if(this.swapAttach[0]){
            this.swapAttach[0].destroy();
        }
        if(this.swapAttach[1]){
            this.swapAttach[1].destroy();
        }
        if(this._pickAttach){
            this._pickAttach.destroy();
        }
        if(this._depthAttach){
            this._depthAttach.destroy();
        }
        if(this._postionTexture){
            this._postionTexture.destroy();
        }
        if(this._normalTexture){
            this._normalTexture.destroy();
        }
        Pass._instance=null;
    }
}
export { Pass }